package com.yjc.drygoods.ware.service.impl;

import com.yjc.common.constant.PurchaseDetailStatusEnum;
import com.yjc.common.constant.PurchaseStatusEnum;
import com.yjc.drygoods.ware.dao.PurchaseDao;
import com.yjc.drygoods.ware.entity.BatchesEntity;
import com.yjc.drygoods.ware.entity.PurchaseDetailEntity;
import com.yjc.drygoods.ware.entity.PurchaseEntity;
import com.yjc.drygoods.ware.entity.SupplierEntity;
import com.yjc.drygoods.ware.service.*;
import com.yjc.drygoods.ware.vo.MergeVo;
import com.yjc.drygoods.ware.vo.PurchaseDoneVo;
import com.yjc.drygoods.ware.vo.PurchaseItemDoneVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yjc.common.utils.PageUtils;
import com.yjc.common.utils.Query;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Slf4j
@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

    @Autowired
    PurchaseDetailService purchaseDetailService;

    @Autowired
    WareSpuService wareSpuService;

    @Autowired
    BatchesService batchesService;

    @Autowired
    SupplierService supplierService;

    @Override
    public PageUtils getAllAssignedPurchaseWithDetail(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<PurchaseEntity>()
                .eq("status", PurchaseStatusEnum.ASSIGNED.getCode());
        String userId = (String) params.get("userId");
        if (!StringUtils.isEmpty(userId)) {
            queryWrapper.eq("assignee_id", userId);
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );

        List<PurchaseEntity> purchaseList = page.getRecords();
        if (purchaseList == null || purchaseList.size() <= 0) {
            return new PageUtils(page);
        }

        List<PurchaseEntity> resList = purchaseList.stream()
                .map(item -> {
                    List<PurchaseDetailEntity> purchaseDetails = purchaseDetailService.list(new QueryWrapper<PurchaseDetailEntity>()
                            .eq("purchase_id", item.getId()).eq("status", PurchaseDetailStatusEnum.ASSIGNED.getCode()));
                    item.setItems(purchaseDetails);
                    return item;
                }).filter(item -> item.getItems() != null && item.getItems().size() > 0).collect(Collectors.toList());
        page.setRecords(resList);
        return new PageUtils(page);

    }

    @Override
    public PageUtils getAllHavedPurchaseWithDetail(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<PurchaseEntity>()
                .eq("status", PurchaseStatusEnum.RECEIVED.getCode());
        String userId = (String) params.get("userId");
        if (!StringUtils.isEmpty(userId)) {
            queryWrapper.eq("assignee_id", userId);
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );

        List<PurchaseEntity> purchaseList = page.getRecords();
        if (purchaseList == null || purchaseList.size() <= 0) {
            return new PageUtils(page);
        }

        List<PurchaseEntity> resList = purchaseList.stream()
                .map(item -> {
                    List<PurchaseDetailEntity> purchaseDetails = purchaseDetailService.list(new QueryWrapper<PurchaseDetailEntity>()
                            .eq("purchase_id", item.getId()).eq("status", PurchaseDetailStatusEnum.BUYING.getCode()));
                    item.setItems(purchaseDetails);
                    return item;
                }).filter(item -> item.getItems() != null && item.getItems().size() > 0).collect(Collectors.toList());
        page.setRecords(resList);
        return new PageUtils(page);

    }

    @Transactional
    @Override
    public void donePurchase(PurchaseDoneVo purchaseDoneVo) {

        //1.改变采购项的状态
        Boolean flage = true; //采购单状态
        List<PurchaseItemDoneVo> items = purchaseDoneVo.getItems();
        List<PurchaseDetailEntity> purchaseDetailEntities = new ArrayList<>();
        for (PurchaseItemDoneVo item : items) {
            PurchaseDetailEntity purchaseDetail = purchaseDetailService.getById(item.getId());
            if (item.getStatus() != null && item.getStatus() == PurchaseDetailStatusEnum.BUYERROR.getCode()) {
                flage = false;
                purchaseDetail.setStatus(item.getStatus());
            } else if (item.getStatus() != null && item.getStatus() == PurchaseDetailStatusEnum.FINISHED.getCode()) {
                //3.将成功采购的进行入库
                //3.1设置采购需求状态
                purchaseDetail.setStatus(item.getStatus());
                //3.2设置采购需求实际采购数量
                if (item.getSpuNum() == null || item.getSpuNum() > 300 || item.getSpuNum() <= 0) {
                    throw new RuntimeException("出错采购需求：" + item.getId() + "  采购数量异常");
                }
                purchaseDetail.setSpuNum(item.getSpuNum());
                //3.3设置采购需求进货单价
                if (item.getSingleSpuPrice() == null
                        || item.getSingleSpuPrice().compareTo(new BigDecimal("2000")) == 1
                        || item.getSingleSpuPrice().compareTo(new BigDecimal("0.1")) == -1) {
                    throw new RuntimeException("出错采购需求：" + item.getId() + "  采购进价异常");
                }
                purchaseDetail.setSingleSpuPrice(item.getSingleSpuPrice());
                //3.4设置采购需求进货总价
                purchaseDetail.setSpuPrice(item.getSingleSpuPrice().multiply(new BigDecimal(item.getSpuNum() + "")));
                //3.5设置采购需求供货商id
                purchaseDetail.setSupplierId(item.getSupplierId());
                //3.6设置采购需求供货商名称
                SupplierEntity supplier = supplierService.getById(item.getSupplierId());
                purchaseDetail.setSupplierName(supplier.getSupplierName());
                //3.7设置采购需求更新时间
                purchaseDetail.setUpdateTime(new Date());
                //3.8设置采购需求批次
                BatchesEntity batches = batchesService.getSpuBatch(purchaseDetail.getSpuId());
                if (batches != null) {
                    purchaseDetail.setBatch(batches.getBatch() + 1);
//                    wareSpuService.updateWareStock(purchaseDetail.getSpuId(), purchaseDetail.getWareId(), purchaseDetail.getSpuNum());
                } else {
                    //第一批次
                    purchaseDetail.setBatch(1);
                }
                //4.更新库存信息
                wareSpuService.updateWareStock(purchaseDetail.getSpuId(), purchaseDetail.getWareId(), purchaseDetail.getSpuNum());
                //3.9设置采购需求失败原因(可选，可能为空)
                purchaseDetail.setReason(item.getReason());

            } else {
                //#检查采购需求状态，一定要保证传过来的状态一定是成功或失败两者之一
                throw new RuntimeException("出错采购需求：" + item.getId() + "  请选择正确采购状态");
            }
//            purchaseDetail.setId(item.getItemId());
            purchaseDetailEntities.add(purchaseDetail);
        }
        purchaseDetailService.updateBatchById(purchaseDetailEntities);
        log.info("purchaseDetailEntities:{}", purchaseDetailEntities);
//        List<Long> resList = purchaseDetailEntities
//                .stream()
//                .filter(item -> item.getStatus() == PurchaseDetailStatusEnum.FINISHED.getCode())
//                .map(PurchaseDetailEntity::getSpuId)
//                .collect(Collectors.toList());

        batchesService.saveOrUpdateBatches(purchaseDetailEntities);

        //2.改变采购单状态
        Long id = purchaseDoneVo.getId();
        PurchaseEntity byId = new PurchaseEntity();
        byId.setId(id);
        if (flage) {
            byId.setStatus(PurchaseStatusEnum.FINISHED.getCode());
        } else {
            byId.setStatus(PurchaseStatusEnum.HASEERROR.getCode());
        }
        for (PurchaseDetailEntity purchaseDetailEntity : purchaseDetailEntities) {
            if (purchaseDetailEntity.getStatus() == PurchaseDetailStatusEnum.FINISHED.getCode()) {
                byId.setAmount(purchaseDetailEntity.getSpuPrice().add(byId.getAmount() == null ? new BigDecimal("0.0") : byId.getAmount()));
            }
        }
        byId.setUpdateTime(new Date());
        this.updateById(byId);


    }


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> purchaseEntityQueryWrapper = new QueryWrapper<>();
        String status = (String) params.get("status");
        if (!StringUtils.isEmpty(status)) {
            purchaseEntityQueryWrapper.eq("status", status);
        }
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            purchaseEntityQueryWrapper.like("assignee_name", key).or().eq("id", key);
        }
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                purchaseEntityQueryWrapper
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveMerge(MergeVo mergeVo) {

        //要在判断采购需求是新建或者是已分配的情况下，才能够对其合并进采购单
        List<Long> items = mergeVo.getItems();
        if (items != null && items.size() > 0) {
            List<PurchaseDetailEntity> purchaseDetails = purchaseDetailService.listByIds(items);
            //整单id
            //合并项集合
            Long purchaseId = mergeVo.getPurchaseId();
            //获取新建或已分配状态的采购需求
            List<PurchaseDetailEntity> collect = purchaseDetails.stream()
                    .filter(item -> item.getStatus() == PurchaseDetailStatusEnum.CREATED.getCode() || item.getStatus() == PurchaseDetailStatusEnum.ASSIGNED.getCode())
                    .collect(Collectors.toList());
            //还要判断是否有新建或者已分配状态的采购需求，没有就不创建采购单
            if (collect == null || collect.size() <= 0) {
                return;
            }
            if (purchaseId == null) {
                PurchaseEntity purchaseEntity = new PurchaseEntity();
                purchaseEntity.setUpdateTime(new Date());
                purchaseEntity.setCreateTime(new Date());
                purchaseEntity.setStatus(PurchaseStatusEnum.CREATED.getCode());
                this.save(purchaseEntity);
                purchaseId = purchaseEntity.getId();
            } else {
                PurchaseEntity purchase = this.getById(purchaseId);
                if (purchase == null || (purchase.getStatus() != PurchaseStatusEnum.CREATED.getCode() && purchase.getStatus() != PurchaseStatusEnum.ASSIGNED.getCode())) {
                    throw new RuntimeException("该采购单不能再被分配采购需求！");
                }
            }
            Long finalPurchaseId = purchaseId;


            List<PurchaseDetailEntity> resList = collect.stream()
                    .map(item -> {
                        item.setPurchaseId(finalPurchaseId);
                        item.setStatus(PurchaseDetailStatusEnum.ASSIGNED.getCode());
                        item.setUpdateTime(new Date());
                        return item;
                    }).collect(Collectors.toList());
            purchaseDetailService.updateBatchById(resList);

            PurchaseEntity purchaseEntityUpdateDate = new PurchaseEntity();
            purchaseEntityUpdateDate.setUpdateTime(new Date());
            purchaseEntityUpdateDate.setId(purchaseId);
            this.updateById(purchaseEntityUpdateDate);
        }
    }

    @Override
    public PageUtils queryPageUnreceiveList(Map<String, Object> params) {
        QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 0).or().eq("status", 1);
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void receivePurchase(List<Long> ids) {
        List<PurchaseEntity> purchaseEntities = this.baseMapper.selectBatchIds(ids);
        if (ids != null && ids.size() > 0) {
            List<PurchaseEntity> collect = purchaseEntities.stream()
                    .filter(item -> {
                        return item.getStatus() == PurchaseStatusEnum.CREATED.getCode() ||
                                item.getStatus() == PurchaseStatusEnum.ASSIGNED.getCode()
                                ? true : false;
                    })
                    .map(purchaseEntity -> {
                        purchaseEntity.setStatus(PurchaseStatusEnum.RECEIVED.getCode());
                        purchaseEntity.setUpdateTime(new Date());
                        return purchaseEntity;
                    }).collect(Collectors.toList());
            this.updateBatchById(collect);
            collect.forEach(i -> {
                List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.listDetailByPurchaseId(i.getId());
                List<PurchaseDetailEntity> collect1 = purchaseDetailEntities.stream()
                        .filter(item -> (item.getStatus() == PurchaseDetailStatusEnum.ASSIGNED.getCode()))
                        .map(pur -> {
                            pur.setStatus(PurchaseDetailStatusEnum.BUYING.getCode());
                            return pur;
                        }).collect(Collectors.toList());
                purchaseDetailService.updateBatchById(collect1);
            });

        }

    }


}